<template>
  <div class="dh-tooltip" v-on="outherEvents"   ref="parentNode">
    <div class="dh-tooltip__trigger" ref="tirggerNode" v-on="evetns">
      <slot></slot>
    </div>
    <Transition :name="transition">
      <div class="dh-tooltip__popper" v-if="isOpen" ref="popperNode">
        <slot name="content">
          {{ content }}
        </slot>
        <div id="arrow" data-popper-arrow></div>
      </div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, reactive, computed } from "vue";
import type { TooltipEmits, TooltipProps, TooltipInstance } from "./type";
import { createPopper } from "@popperjs/core";
import type { Instance } from "@popperjs/core";
import { debounce } from "lodash-es";
import useClickoutSide from "@/hooks/useClickoutSide";
defineOptions({
  name: "DhTooltip",
});
let isOpen = ref(false);
let tirggerNode = ref<HTMLElement>();
let popperNode = ref<HTMLElement>();
let parentNode = ref<HTMLElement>();
let evetns = reactive<any>({});
let outherEvents = reactive<any>({});
let popperInstance: Instance | null = null;
const props = withDefaults(defineProps<TooltipProps>(), {
  placement: "bottom",
  trigger: "hover",
  transition: "fade",
  openDelay: 0,
  closeDelay: 0,
});

//计算参数
let popperOptions = computed(() => {
  return {
    placement: props.placement,
    modifiers: [
      {
        name: "offset",
        options: {
          offset: [0, 9],
        },
      },
    ],
    ...props.popperOptions,

  };
});

const emits = defineEmits<TooltipEmits>();
watch(
  isOpen,
  (newValue) => {
    if (newValue) {
      if (tirggerNode.value && popperNode.value) {
        popperInstance = createPopper(
          tirggerNode.value,
          popperNode.value,
          popperOptions.value
        );
      } else {
        popperInstance?.destroy();
      }
    }
  },
  { flush: "post" }
);
const changeOpen = () => {
  if (isOpen.value) {
    close();
   
    
  } else {
    open();
  }
};
//打开
const open = debounce(() => {
  if(isOpen.value) return
  
  isOpen.value = true;
  emits("Tooltip-change", true);
}, props.openDelay);
//关闭
const close = debounce(() => {
  if(!isOpen.value) return
 
  
  isOpen.value = false;
  emits("Tooltip-change", false);
}, props.closeDelay);
const addEvent = () => {
  if (props.trigger === "hover") {
    evetns["mouseenter"] = open;
    outherEvents["mouseleave"] = close;
    // document.querySelector('.dh-tooltip')?.addEventListener('mouseleave',close)
  } else if (props.trigger === "click") {
    evetns["click"] = changeOpen;
  }
};
watch(
  () => props.trigger,
  (newValue, oldValue) => {
    if (newValue !== oldValue && !props.visible) {
      evetns = {};
      outherEvents = {};
    // document.querySelector('.dh-tooltip')?.removeEventListener('mouseleave',close)

      addEvent();
    }
  }
);
if (!props.visible) {
  addEvent();
}
watch(
  () => props.visible,
  (newValue) => {
    if (newValue) {
      evetns = {};
      outherEvents = {};
    // document.querySelector('.dh-tooltip')?.removeEventListener('mouseleave',close)

    } else {
      addEvent();
    }
  }
);
useClickoutSide(parentNode, () => {
  if (props.trigger === "click" && isOpen.value && props.visible == false) {
    close();
    return
  }
  if(isOpen.value) {
    emits("click-outside",true)
  }
});
defineExpose<TooltipInstance>({
  show: open,
  hide: close,
});
</script>

<style scoped></style>
